<template>
  <div class="demo">
    <h2 v-if="title">{{ title }}</h2><template v-else />
    <div class="description" v-if="description || $slots.default">
      <slot>
        <template v-if="description">{{ description }}</template><template v-else />
      </slot>
    </div>
    <template v-if="code">
      <div class="preview">
        <div>预览</div>
        <component :is="demo"></component>
      </div>
      <div class="ops">
        <ee-button icon="search" @click="expand = true; $el.querySelector('[contenteditable]').focus()">
          试试代码
        </ee-button>
        <ee-button icon="add" @click="copy">
          复制代码
        </ee-button>
        <ee-button :icon="expand ? 'up' : 'down'" @click="expand = !expand">
          显示代码
        </ee-button>
      </div>
      <div :class="`code eet visible ${expand ? 'in' : ''}`">
        <code-mirror v-model="editingCode" v-bind="editorSetting" @change="change" />
        <div class="hide-code" v-if="expand">
          <ee-button icon="reset" @click="editingCode = code">
            重置代码
          </ee-button>
          <ee-button icon="reset" @click="save">
            保存代码
          </ee-button>
          <ee-button icon="up" @click="expand = false">
            隐藏代码
          </ee-button>
        </div><template v-else />
      </div>
    </template><template v-else />
  </div>
</template>


<script type="text/javascript">
import { compileVue } from './code';
import CodeMirror from 'vue-codemirror6';
import { vue } from '@codemirror/lang-vue'
import { oneDark } from '@codemirror/theme-one-dark'
import { injectStore } from 'ee-vuex';

const lang = vue({})

export default injectStore({
  name: "doc-demo",
  components: {
    CodeMirror
  },
  emits: ['onSave'],
  data() {
    return {
      expand: false,
      _code: undefined,
      compiling: undefined,
      demo: undefined,
      editorSetting: {
        basic: true,
        wrap: true,
        tab: true,
        // readonly: true,
        tabSize: 2,
        lang: lang,
        extensions: [oneDark],
      },
    }
  },
  props: {
    title: String,
    description: String,
    code: {
      set(value) {
        this.editingCode = value;
      }
    },
  },
  computed: {
    editingCode: {
      get() { return this._code; },
      set(value) {
        this._code = value;
        if (this.demo) {
          if (this.compiling)
            clearTimeout(this.compiling);
          this.compiling = setTimeout(() => {
            this.demo = compileVue(value);
            this.compiling = undefined;
          }, 1000)
        } else {
          this.demo = compileVue(value);
        }
      }
    }
  },
  // emits: ['childEvent'],
  methods: {
    copy() {
      console.log('code?', this, this.code)
      navigator.clipboard.writeText(this.code);
      // 弹窗复制成功
      this.dialog('复制成功')
    },
    save() {
      this.code = this.editingCode;
      console.log('保存代码')
      this.$emit('save', this.code, this)
    }
  },
  mounted() {
  },
})
</script>

<style lang="scss" scoped>
.demo {
  border: 1px solid var(--line6);
  border-radius: .25em;
  padding-top: 1.5em;
  overflow: hidden;

  > .description {
    line-height: 2;
    padding: .75em 1.5em;
    margin: 0;
  }

  > :first-child {
    margin: 0;
    padding: 0 1em;
  }

  > :only-child {
    padding-top: 0;
    padding-bottom: 1.5em;
  }

  .preview {
    margin-top: .5em;
    border: solid var(--line6);
    border-width: 1px 0;
    position: relative;
    padding: 2em 1.5em;

    > :first-child {
      background-color: var(--ee-bgcolor);
      padding: 0 1em;
      font-size: .875em;
      position: absolute;
      top: 0;
      transform: translateY(-50%);
    }
  }

  .ops {
    display: flex;
    justify-content: flex-end;

    .ee-button {
      border: 0;
      border-radius: 0;
      flex: 1;
    }
  }

  .code {
    .hide-code {
      width: 100%;
      position: sticky;
      bottom: 0;
      display: flex;

      .ee-button {
        flex: 1;
        border: 0;
        border-radius: 0;
      }
    }
  }
}
</style>